/**
 * 自定义基本弧线布局
 * @author houjinhui
 */
import G6 from '@antv/g6'
import { BASIC_ARC } from '@/components/graph-analysis/right-drawer/style-layout-config/style-layout'

interface KeyValue {
  [key: string]: any
}

/**
 * 自定义画布布局
 */
export default function registerBasicArcG6Layout() {
  // 基础弧线布局
  G6.registerLayout(BASIC_ARC, {
    // 定义自定义行为的默认参数，会与用户传入的参数进行合并, 这里的参数和 style-layout.ts 里的参数保持一致
    getDefaultCfg() {
      return {
        nodeSpacing: 5, // 节点间的间隙
      }
    },
    /**
     * 初始化
     * @param {Object} data 数据
     */
    init(data: any) {
      const self = this // this 指向当前布局
      self.nodes = data.nodes
      self.edges = data.edges
    },
    /**
     * 执行布局
     */
    execute() {
      const self: any = this
      const { edges, nodes, width, height } = self
      const nodesLength = nodes.length
      const horiPadding = 40
      const begin = [horiPadding, height * 0.7] // 起点位置
      const end = [width - horiPadding, height * 0.7] // 结束节点位置
      const xLength = end[0] - begin[0] // 节点x范围差
      const yLength = end[1] - begin[1] // 节点y范围差
      const xSeparator = xLength / nodesLength // x 方向每个节点的宽度
      const ySeparator = yLength / nodesLength // y 方向每个节点的高度
      nodes.forEach((node: any, index: number) => {
        node.x = begin[0] + index * xSeparator
        node.y = begin[1] + index * ySeparator
      })
      edges.forEach((edge: any) => {
        const source: any = nodes.find((node: any) => {
          return node.id === edge.source
        })
        const target: any = nodes.find((node: any) => {
          return node.id === edge.target
        })
        const sourceTargetDistanceDifference: any = source.x - target.x
        if (edge.controlPoints) {
          delete edge.controlPoints
        }
        edge.type = 'quadratic'
        edge.curveOffset = sourceTargetDistanceDifference / 1.5
        edge.curvePosition = 0.5
      })
    },
    /**
     * 根据传入的数据进行布局
     * @param {Object} data 数据
     */
    layout(data: any) {
      const self = this
      self.init(data)
      self.execute()
    },
    /**
     * 更新布局配置，但不执行布局
     * @param {Object} cfg 需要更新的配置项
     */
    updateCfg(cfg: any) {
      const self = this
      G6.Util.mix(self, cfg)
    },
    /**
     * 销毁
     */
    destroy() {
      const self = this
      self.positions = null
      self.nodes = null
      self.edges = null
      self.destroyed = true
    },
  })
}
